<?php
// +----------------------------------------------------------------------
// | B5ThinkCMF [快捷通用基础开发管理平台]
// +----------------------------------------------------------------------
// | Author: 冰舞 <357145480@qq.com>
// +----------------------------------------------------------------------
declare (strict_types=1);

namespace app\admin\controller\contract;

use app\admin\BaseController;
use app\admin\extend\helpers\TraitActionHelper;
use app\admin\extend\services\contract\ContractService;
use app\common\helpers\ExportHelper;
use app\common\helpers\Result;
use app\common\helpers\Tools;
use app\common\model\contract\Contract;
use app\common\model\contract\SigningContract;
use app\Request;
use think\facade\Db;
use think\facade\Log;
use think\facade\Session;
use think\facade\Validate;


class ContractController extends BaseController
{
    use TraitActionHelper;

    protected $model = Contract::class;


    public function indexAction(Request $request)
    {
        if ($request->isPost()) {
            $params = $request->post();
            if (method_exists($this, 'indexBefore')) {
                $params = $this->indexBefore($params);
            }
            //是否是树形tree，展示所有数据
            $isTree = $params['isTree'] ?? 0;

            //是否为导出excel，展示所有数据
            $isExport = $params['isExport'] ?? 0;

            $query = Db::table($this->model::tableName());
            $query = $this->indexWhere($query, $params);

            //操作查询对象，可以进行语句处理以及数据权限处理
            $extend = [];
            $queryResult = $this->indexQuery($query);
            if (is_array($queryResult)) {
                $query = $queryResult['query'];
                $extend = $queryResult['extend'] ?? [];
            } else {
                $query = $queryResult;
            }

            //是否分页
            if (!$isTree && !$isExport) {
                $pageSize = intval($params['pageSize'] ?? 10);
                $pageNum = intval($params['pageNum'] ?? 1);
                $pageNum = $pageNum < 1 ? 1 : $pageNum;
                $count = $query->count();
                $query = $query->page($pageNum, $pageSize);
            }
            $list = $query->select()->toArray();

            if ($isTree || $isExport) {
                $count = count($list);
            }
            //结果查询后的处理
            if (method_exists($this, 'indexAfter')) {
                $list = $this->indexAfter($list);
            }

            //导出操作
            if ($isExport) {
                //结果查询后的处理
                $export_data = $this->exportBefore($list);
                $excel_path = (new ExportHelper($export_data))->export();
                return Result::success($excel_path);
            } else {
                foreach ($list as $k => $v) {
                    $list[$k]['initiator_cn'] = Db::name('admin')->where('id', $v['initiator'])->value('username');
                    $list[$k]['created_at'] = date('Y/m/d', $v['created_at']);
                }
                return Result::success('', $list, ['total' => $count, 'extend' => $extend]);
            }
        } else {
            $type = $request->get('type', '');
            $total = [
                'sending_total' => (new Contract())->getStatusCount(),
                'recycling_total' => (new Contract())->getStatusCount(1),
                'achieve_total' => (new Contract())->getStatusCount(2),
                'expire_total' => (new Contract())->getStatusCount(3),
            ];
            return $this->render('', ['type' => $type, 'total' => $total]);
        }
    }


    public function addAction(Request $request)
    {
        if ($request->isPost()) {
            $students = $request->post('students') ?? [];

            $data = [
                'title' => $request->post('title'),
                'contract_file_name' => $request->post('contract'),
                'contract_url' => $request->post('contract_url') ?? '',
                'attachment' => $request->post('attachment') ?? '',
                'attachment_url' => $request->post('attachment_url') ?? '',
                'sending_num' => count($students),
                'preview_url' => join(',', $request->post('preview_url', [])),
                'type' => $request->post('type'),
                'initiator' => Tools::getOperator(),
            ];

            $validate = Validate::rule([
                'title' => 'require',
                'contract_url' => 'require',
            ])->message([
                'title.require' => '合同名称不能为空',
                'contract_url.require' => '合同上传失败，请重新上传',
            ]);
            if (!$validate->check($data)) {//
                return Result::error($validate->getError());
            }

            if ($data['type'] == 1 && count($students) == 0) {
                return Result::error('请上传学员名单');
            }

            $contract = new Contract();
            $type = (int)$data['type'];
            if (!in_array($type, [1, 2])) {
                return Result::error('类型错误');
            }
            if (Db::name('contract')->where('title', $data['title'])->count()) {
                return Result::error('合同名称重复');
            }
            switch ($type) {
                case 1:
                    if (!$students) {
                        return Result::error('请上传学员名单');
                    }
                    Db::startTrans();
                    try {
                        $arr = [];
                        $id = $contract->insert($data, true);
                        if (!$id) {
                            Db::rollback();
                            return Result::error('网络错误,请重试');
                        }
                        foreach ($students as $student) {
                            $arr[] = [
                                'contract_id' => $id,
                                'index' => $student['index'],
                                'childs_name' => $student['childName'],
                                'parent_wechat' => $student['wechat'],
                                'parent_phone' => $student['phone'],
                                'grading_situation' => $student['gradation'],
                                'expired_at' => strtotime('+1 month', time()),
                                'document_url' => '',
                            ];
                        }
                        $res = (new SigningContract())->insertAll($arr);
                        if (!$res) {
                            Db::rollback();
                            return Result::error('网络错误,请重试');
                        }
                        //更新二维码
//                        $urlLink = \Wechat::generateUrlLink("id=".$id);
                        if (!(new Contract())->update(['id' => $id], [
                            'sign_qr_code' => \Wechat::getQRCode("id=" . $id, 'pages/home/index'),
                            'sign_link' => \Wechat::generateUrlLink("id=" . $id, 'pages/home/index')
                        ])) {
                            Db::rollback();
                            return Result::error('网络错误,请重试');
                        }
                        Db::commit();
                    } catch (\Throwable $throwable) {
                        Db::rollback();
                        return Result::error("网络错误,请重试 【{$throwable->getMessage()}】");
                    }
                    break;
                case 2:
                    Db::startTrans();
                    try {
                        $id = $contract->insert($data, true);
                        if (!$id) {
                            Db::rollback();
                            return Result::error('网络错误,请重试');
                        }
                        if (!(new Contract())->update(['id' => $id], [
                            'sign_qr_code' => \Wechat::getQRCode("id=" . $id),
                            'sign_link' => \Wechat::generateUrlLink("id=" . $id)
                        ])) {
                            Db::rollback();
                            return Result::error('网络错误,请重试');
                        }
                        Db::commit();
                    } catch (\Throwable $throwable) {
                        Db::rollback();
                        return Result::error("网络错误,请重试 【{$throwable->getMessage()}】");
                    }
                    break;
            }
            //验证
            return Result::success('保存成功');
        } else {
            return $this->addRender($request);
        }
    }

    /**
     * 公共编辑action
     * @param Request $request
     * @return string|\think\response\Json
     */
    public function editAction(Request $request)
    {
        if ($request->isPost()) {
            $data = $request->post();
            //验证
            if ($this->validate ?? false) {
                //验证前数据处理
                $data = $this->validateBefore($data, 'edit');
                if (!is_array($data)) {
                    return Result::error($data);
                }

                $res = validate($this->validate)->scene('edit')->check($data);
                if ($res !== true) {
                    return Result::error($res);
                }
            }
            //数据预处理
            $data = $this->saveBefore($data, 'edit');
            if (!is_array($data)) {
                return Result::error($data);
            }

            $result = $this->model::bUpdate($data);
            if ($result === false) {
                return Result::error('保存失败');
            }
            if ($result) {
                $this->saveAfter($data, 'edit');
            }
            return Result::success('保存成功');
        } else {
            $id = $request->get('id', 0);
            if (!$id) {
                return $this->toError('参数错误');
            }
            $info = $this->model::bFind($id);
            if (!$info) {
                return $this->toError('信息不存在');
            }
            $info['preview_url'] = explode(',', $info['preview_url']);
            $info['student_list'] = SigningContract::bSelect(['contract_id' => $info['id']]);
            foreach ($info['student_list'] as $k => $value) {
                $info['student_list'][$k]['success_at'] = !empty($value['success_at']) ? date('Y-m-d H:i:s', $value['success_at']) : '-';
                $info['student_list'][$k]['status_cn'] = (function () use ($value) {
                    if ($value['is_agree'] == 0) {
                        if ($value['expired_at'] < time()) {
                            return '已超时';
                        }
                        return '-';
                    } else {
                        return '已同意';
                    }
                })();
            }
            return $this->editRender($info, $request);
        }
    }

    public function downloadAction(Request $request)
    {
        $id = $request->get('id', 0);
        if (!$id) {
            return $this->toError('参数错误');
        }
        $info = $this->model::bFind($id);
        if (!$info) {
            return $this->toError('信息不存在');
        }
        $info['preview_url'] = explode(',', $info['preview_url']);
        $info['partners'] = Db::name('partners')->where(['contract_id' => $info['id']])->select()->toArray();

        foreach ($info['partners'] as $k => $v) {
            $info['partners'][$k]['created_at'] = date('Y/m/d H:i', $v['created_at']);
        }
        return $this->editRender($info, $request);
    }

    public function adduserAction(Request $request)
    {
        if ($request->isPost()) {
            $data = $request->post();
            $arr = [
                'contract_id' => $data['id'],
                'index' => $data['index'],
                'childs_name' => $data['childName'],
                'parent_wechat' => $data['wechat'],
                'parent_phone' => $data['phone'],
                'grading_situation' => $data['gradation'],
                'expired_at' => strtotime('+1 month', time()),
                'document_url'=>''
            ];
            if ((new SigningContract())->insert($arr)) {
                Db::name('contract')->where('id', $data['id'])->inc('sending_num')->update();
                return Result::success('保存成功');
            }
            return Result::error('保存失败');
        }
        return $this->render();
    }

}
